package iec870_5

const (
	IFrame FrameType = 0
	SFrame FrameType = 1
	UFrame FrameType = 3
)

type FrameType uint8

type controlDomain struct {
	frameType FrameType //0:I,1:S,3:U
}
type iFrameControlDomain struct {
	controlDomain
	sendCounter    uint16 //发送计数器
	receiveCounter uint16 //接收计数器
}

func (_this *iFrameControlDomain) getControlDomain() [4]byte {
	controlBuffer := [4]byte{}
	controlBuffer[0] = byte(_this.sendCounter) & 0xFE
	controlBuffer[1] = byte(_this.sendCounter>>8) & 0xFF
	controlBuffer[2] = byte(_this.receiveCounter) & 0xFE
	controlBuffer[3] = byte(_this.receiveCounter>>8) & 0xFF
	return controlBuffer
}

func (_this *iFrameControlDomain) toControlDomain(buffer [4]byte) icontrolDomain {
	_this.sendCounter = uint16(buffer[0]) | uint16(buffer[1])<<8
	_this.receiveCounter = uint16(buffer[2]) | uint16(buffer[3])<<8
	return _this
}

func (_this *iFrameControlDomain) getFrameType() FrameType {
	return IFrame
}

type sFrameControlDomain struct {
	controlDomain
	receiveCounter uint16 //接收计数器
}

func (_this *sFrameControlDomain) getControlDomain() [4]byte {
	controlBuffer := [4]byte{}
	controlBuffer[0] = 0x01
	controlBuffer[1] = 0x00
	controlBuffer[2] = byte(_this.receiveCounter) & 0xFE
	controlBuffer[3] = byte(_this.receiveCounter>>8) & 0xFF
	return controlBuffer
}

func (_this *sFrameControlDomain) toControlDomain(buffer [4]byte) icontrolDomain {
	_this.receiveCounter = uint16(buffer[2]) | uint16(buffer[3])<<8
	return _this
}
func (_this *sFrameControlDomain) getFrameType() FrameType {
	return SFrame
}

type uFrameControlDomain struct {
	controlDomain
	test  bool //测试标志
	stop  bool //停止标志
	start bool //开启标志
}

func (_this *uFrameControlDomain) getControlDomain() [4]byte {
	controlBuffer := [4]byte{}
	controlBuffer[0] = 0x01
	controlBuffer[1] = 0x00
	controlBuffer[2] = 0x00 //byte(_this.receiveCounter) & 0xFE
	controlBuffer[3] = 0x00 //byte(_this.receiveCounter>>8) & 0xFF
	return controlBuffer
}
func (_this *uFrameControlDomain) toControlDomain(buffer [4]byte) icontrolDomain {
	return _this
}
func (_this *uFrameControlDomain) getFrameType() FrameType {
	return UFrame
}

type icontrolDomain interface {
	getControlDomain() [4]byte
	toControlDomain([4]byte) icontrolDomain
	getFrameType() FrameType
}
